package com.newlink.building.main.ui

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.newlink.building.library_rino.ConnectionController
import com.newlink.building.common_base.base.NL_BaseMvpActivity
import com.newlink.building.common_base.event.CallCreateActionBean
import com.newlink.building.common_base.event.CallCreateBean
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.TYPE_CALL_SEND_CREATE_CHANNEL_REQUEST_PROPERTY_MANAGER_SEARCH
import com.newlink.building.common_base.event.TYPE_CALL_SEND_CREATE_CHANNEL_RESULT_PROPERTY_MANAGER_SEARCH
import com.newlink.building.common_base.event.TokenVo
import com.newlink.building.common_base.ext.showToast
import com.newlink.building.common_base.model.bean.PropertyManagerData
import com.newlink.building.common_base.model.bean.RoomData
import com.newlink.building.common_base.model.bean.RoomUserData
import com.newlink.building.common_base.utils.KeyBoardUtil
import com.newlink.building.common_base.utils.PermissionHelper
import com.newlink.building.common_base.widget.CustomMessageDialog
import com.newlink.building.common_base.widget.SpaceItemDecoration
import com.newlink.building.main.R
import com.newlink.building.main.adapter.Module_Main_ResidentSearchAdapter
import com.newlink.building.main.databinding.ActivityResidentSearchBinding
import com.newlink.building.main.mvp.contract.Module_Main_ResidentSearchContract
import com.newlink.building.main.mvp.presenter.Module_Main_ResidentSearchPresenter
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.manager.Module_Phone_VoipController
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.linphone.core.Call
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub

/**
 * Created by xiaodong on 2025/3/11.
 */
class Module_Main_ResidentSearchActivityNL :
    NL_BaseMvpActivity<Module_Main_ResidentSearchContract.View, Module_Main_ResidentSearchContract.Presenter>(),
    Module_Main_ResidentSearchContract.View {
    var localChannelName: String = ""
    var tokenVo: TokenVo? = null
    var mPropertyManagerData: PropertyManagerData? = null
    var mRoomUserData: RoomUserData? = null
    private lateinit var mBinding: ActivityResidentSearchBinding
    private val mAdapter = Module_Main_ResidentSearchAdapter(mutableListOf())
    override fun attachLayoutRes(): View? {
        mBinding = ActivityResidentSearchBinding.inflate(layoutInflater)
        return mBinding.root
    }

    override fun initData() {
    }

    override fun createPresenter() = Module_Main_ResidentSearchPresenter()

    override fun initView() {
        mBinding.tvResultCount.text = getString(R.string.result_resident_search, 0)
        mBinding.titleBar.tvTitleBarCenter.text = getText(R.string.resident_str)
        mBinding.searchIcon.setOnClickListener {
            searchAction()
        }
        mBinding.recyclerView.apply {
            adapter = mAdapter
            layoutManager = LinearLayoutManager(this@Module_Main_ResidentSearchActivityNL)
            addItemDecoration(SpaceItemDecoration(this@Module_Main_ResidentSearchActivityNL))
        }

        mBinding.etSearch.setOnEditorActionListener { v, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                searchAction()
            }
            false
        }

        mBinding.etSearch.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                if (p0?.length == 0) {
                    mBinding.ivClear.visibility = View.GONE
                } else {
                    mBinding.ivClear.visibility = View.VISIBLE
                }
            }

            override fun afterTextChanged(s: Editable?) {
            }

        })

        mBinding.ivClear.setOnClickListener {
            mBinding.etSearch.text?.clear()
        }

        showSoftInputFromWindow(mBinding.etSearch)

        mAdapter.setOnItemClickListener { _, _, position ->

            when (mAdapter.getItem(position)) {
                is RoomData -> {
                    Intent(this, Module_Main_RoomUserActivityNL::class.java).run {
                        putExtra("mRoomData", mAdapter.getItem(position) as RoomData)
                        startActivity(this)
                    }
                }

                is PropertyManagerData -> {

                    mPropertyManagerData = mAdapter.getItem(position) as PropertyManagerData
//                    Intent(this, PropertyManagerDetailActivity::class.java).run {
//                        putExtra("mManagerData", mAdapter.getItem(position) as PropertyManagerData)
//                        startActivity(this)
//                    }
                    if (!PermissionHelper.required(this)
                            .hasPermission(Manifest.permission.RECORD_AUDIO)
                    ) {
                        checkAudioPermission()
                    } else {
//                    makeCall()
                        sendCreateChannelEvent()
                    }
                }

                is RoomUserData -> {
                    mRoomUserData = mAdapter.getItem(position) as RoomUserData
                    if (!PermissionHelper.required(this)
                            .hasPermission(Manifest.permission.RECORD_AUDIO)
                    ) {
                        checkAudioPermission()
                    } else {
//                    makeCall()
                        sendCreateChannelEvent()
                    }
                }
            }
        }
        coreContext.core.addListener(coreListener)
    }

    override fun getPropertyUserListSuccess(data: MutableList<PropertyManagerData>?) {
        val filteredData = data?.filter { it.id != userId.toString() }
        filteredData?.let {
            mAdapter.setNewInstance(filteredData?.toMutableList())
        }
        mPresenter?.getRoomUserList(accessToken, "", mBinding.etSearch.text.toString())
//        mPresenter?.getRoomList(accessToken, "", mBinding.etSearch.text.toString())

    }

    override fun getRoomListSuccess(data: MutableList<RoomData>?) {
        val currentData = mAdapter.data.toMutableList()
        data?.let {
            currentData.addAll(it)
        }

        if (currentData.isNotEmpty()) {
            mBinding.viewEmptyData.visibility = View.GONE
            mBinding.llSearchResult.visibility = View.VISIBLE
            mBinding.tvResultCount.visibility = View.VISIBLE
            mBinding.tvResultCount.text =
                getString(R.string.result_resident_search, currentData?.size)
            mAdapter.setNewInstance(currentData)
        } else {
            mBinding.viewEmptyData.visibility = View.VISIBLE
            mBinding.llSearchResult.visibility = View.GONE
            mBinding.tvResultCount.visibility = View.GONE
            mBinding.tvResultCount.text = getString(R.string.result_resident_search, 0)
        }
    }

    override fun getRoomUserListSuccess(data: MutableList<RoomUserData>) {
        val currentData = mAdapter.data.toMutableList()
        data?.let {
            currentData.addAll(it)
        }
        if (currentData.isNotEmpty()) {
            mAdapter.setNewInstance(currentData)
        }
        mPresenter?.getRoomList(accessToken, "", mBinding.etSearch.text.toString())
    }

    private fun showSoftInputFromWindow(editText: EditText) {
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
        editText.isFocusable = true
        editText.isFocusableInTouchMode = true
        editText.requestFocus()
    }

    private fun searchAction() {
        val searchText = mBinding.etSearch.text.toString()
        if (searchText.isNotEmpty()) {
            mPresenter?.getPropertyUserList(
                accessToken,
                projectId,
                mBinding.etSearch.text.toString()
            )
        }

        mBinding.etSearch.clearFocus()
        KeyBoardUtil.hideKeyBoard(this, mBinding.etSearch)
    }

    private fun checkAudioPermission() {
        val message = getString(
            R.string.common_permission_audio_message,
            getString(R.string.common_permission_to_setting),
            getString(R.string.common_permission_microphone)
        )
        CustomMessageDialog(this).setTitle(getString(R.string.common_permission_title))
            .setMessage(message)

            .setNegativeButton(
                getString(R.string.cancel_dialog_custom)
            ) { dialog ->
                dialog.dismiss()
                showToast(getString(R.string.common_permission_cancel_alert))
            }
            .setPositiveButton(
                getString(R.string.common_permission_to_setting)
            ) { dialog ->
                requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0)
                dialog.dismiss()
            }.show()
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray,
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == 0) {
            for (i in permissions.indices) {
                when (permissions[i]) {
                    Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        //给了权限
                        sendCreateChannelEvent()
                    } else {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(
                                this,
                                Manifest.permission.RECORD_AUDIO
                            )
                        ) {
                            //拒绝
                            checkAudioPermission()
                        } else {
                            openAppSettings()
                        }
                    }
                }
            }
        }
    }

    private fun openAppSettings() {
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        val uri = Uri.fromParts("package", packageName, null)
        intent.data = uri
        startActivity(intent)
    }

    fun sendCreateChannelEvent() {
        if (Module_Phone_VoipController.get().isCallingState()) {
            showToast(getString(R.string.outgoing_call_not_invite_again))
            return
        }
        val sipMsgEvent = MessageEvent(
            TYPE_CALL_SEND_CREATE_CHANNEL_REQUEST_PROPERTY_MANAGER_SEARCH,
            CallCreateActionBean(aid = agoraId)
        )
        EventBus.getDefault().post(sipMsgEvent)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMsgReceived(event: MessageEvent) {
        when (event.msgType) {
            TYPE_CALL_SEND_CREATE_CHANNEL_RESULT_PROPERTY_MANAGER_SEARCH -> {
                val callCreateBean = event.msgContent as CallCreateBean?
                localChannelName = callCreateBean?.data?.rtcToken?.channelName.orEmpty()
                tokenVo = callCreateBean?.data
                makeCall()
            }
        }
    }

    private val coreListener = object : CoreListenerStub() {
        override fun onCallStateChanged(
            core: Core,
            call: Call,
            state: Call.State,
            message: String,
        ) {
            when (state) {
                /**
                 * 由于在coreContext里OutgoingInit时会确保清除ChannelName,家庭成员呼叫是自己创建的ChannelName需要重新设置一下
                 */
                Call.State.OutgoingProgress -> {
                    if (localChannelName.isNotEmpty()) {
                        ConnectionController.getInstance(applicationContext)
                            .setRemoteChannelName(localChannelName)
                    }
                    if (tokenVo != null) {
                        ConnectionController.getInstance(applicationContext)
                            .convert2AgoraUserToken(tokenVo, agoraId, agoraAppId)
                    }
                }

                else -> {}
            }
        }
    }

    private fun makeCall() {
        if (mPropertyManagerData != null) {
            Module_Phone_VoipController.get()
                .makeAudioCall(mPropertyManagerData?.aid.toString(), mPropertyManagerData?.name)
        }
        if (mRoomUserData != null) {
            Module_Phone_VoipController.get().makeAudioCall(mRoomUserData?.aid.toString(), mRoomUserData?.name)
        }
        mPropertyManagerData = null
        mRoomUserData = null
    }

    override fun onDestroy() {
        super.onDestroy()
        coreContext.core.removeListener(coreListener)
    }
}